package www.albertzhe.config;

import org.apache.http.client.config.RequestConfig;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import www.albertzhe.manager.http.ClearConnectionsHandler;
import www.albertzhe.manager.http.HttpClientOperate;
import www.albertzhe.manager.http.iamp.IampRequest;

@Configuration
public class NetBean {
    @Value("${http.pool.maxTotal}")
    private Integer maxTotal;
    @Value("${http.pool.defaultMaxPerRoute}")
    private Integer defaultMaxPerRoute;

    @Value("${http.request.connectTimeout}")
    private Integer connectTimeout;
    @Value("${http.request.connectionRequestTimeout}")
    private Integer connectionRequestTimeout;
    @Value("${http.request.socketTimeout}")
    private Integer socketTimeout;
    @Value("${http.request.staleConnectionCheckEnabled}")
    private boolean staleConnectionCheckEnabled;
    @Value("${http.request.uri.iamp}")
    private String iampURI;

    @Value("${http.cron.cleanTime}")
    private Long cleanTime;
    
    
    /**
     * 首先实例化一个连接池管理器，设置最大连接数、并发连接数
     * 
     * @return
     */
    @Bean(name = "httpClientConnectionManager")
    public PoolingHttpClientConnectionManager getHttpClientConnectionManager() {
        PoolingHttpClientConnectionManager httpClientConnectionManager = new PoolingHttpClientConnectionManager();
        // 最大连接数
        httpClientConnectionManager.setMaxTotal(maxTotal);
        // 并发数
        httpClientConnectionManager.setDefaultMaxPerRoute(defaultMaxPerRoute);
        return httpClientConnectionManager;
    }

    /**
     * 实例化连接池，设置连接池管理器。<br/>
     * 这里需要以参数形式注入上面实例化的连接池管理器
     * 
     * @param httpClientConnectionManager
     * @return
     */
    @Bean(name = "httpClientBuilder")
    public HttpClientBuilder getHttpClientBuilder(
            @Qualifier("httpClientConnectionManager") PoolingHttpClientConnectionManager httpClientConnectionManager) {
        // HttpClientBuilder 中的构造方法被 protected 修饰，所以这里不能直接使用 new 来实例化一个
        // HttpClientBuilder；
        // 可以使用 HttpClientBuilder 提供的静态方法 create() 来获取 HttpClientBuilder 对象。
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        httpClientBuilder.setConnectionManager(httpClientConnectionManager);
        return httpClientBuilder;
    }

    /**
     * 注入连接池，用于获取 httpClient
     * 
     * @param httpClientBuilder
     * @return
     */
    @Bean(name="closeableHttpClient")
    public CloseableHttpClient getCloseableHttpClient(
            @Qualifier("httpClientBuilder") HttpClientBuilder httpClientBuilder) {
        return httpClientBuilder.build();
    }

    /**
     * Builder 是 RequestConfig 的一个内部类，通过 RequestConfig 的 custom 方法来获取到一个 Builder 对象
     * 设置 builder 的连接信息；
     * 这里还可以设置 proxy，cookieSpec 等属性。有需要的话可以在此设置
     * 
     * @return
     */
    @SuppressWarnings("deprecation")
    @Bean(name = "builder")
    public RequestConfig.Builder getBuilder() {
        RequestConfig.Builder builder = RequestConfig.custom();
        return builder.setConnectTimeout(connectTimeout)
                .setConnectionRequestTimeout(connectionRequestTimeout)
                .setSocketTimeout(socketTimeout)
                .setStaleConnectionCheckEnabled(staleConnectionCheckEnabled);
    }
    /**
     * 使用 builder 构建一个 RequestConfig 对象
     * 
     * @param builder
     * @return
     */
    @Bean(name="requestConfig")
    public RequestConfig getRequestConfig(@Qualifier("builder") RequestConfig.Builder builder) {
        return builder.build();
    }

    @Bean
    public ClearConnectionsHandler getClearConnectionsHandler(
            @Qualifier("httpClientConnectionManager")HttpClientConnectionManager httpClientConnectionManager) {
        return new ClearConnectionsHandler(httpClientConnectionManager, cleanTime);
    }
    
    @Bean(name="httpClientOperate")
    public HttpClientOperate getHttpClientOperate() {
        return new HttpClientOperate();
    }
    
    @Bean("iampRequest")
    public IampRequest getIampRequest() {
        return new IampRequest(iampURI);
    }
}
